<?php
/**
 * Joom!Fish - Multi Lingual extention and translation manager for Joomla!
 * Copyright (C) 2003-2007 Think Network GmbH, Munich
 *
 * All rights reserved.  The Joom!Fish project is a set of extentions for
 * the content management system Joomla!. It enables Joomla!
 * to manage multi lingual sites especially in all dynamic information
 * which are stored in the database.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
 *
 * The "GNU General Public License" (GPL) is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * -----------------------------------------------------------------------------
 * $Id: admin.joomfish.php 445 2007-04-13 18:15:17Z akede $
 *
*/

defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

/**
 * The JoomFish Tasker manages the general tasks within the Joom!Fish admin interface
 *
 */
class JoomfishControler extends mosAbstractTasker {

	/** @var string		current used task */
	var $task=null;

	/** @var string		action within the task */
	var $act=null;

	/** @var array		int or array with the choosen list id */
	var $cid=null;

	/** @var string		file code */
	var $fileCode = null;

	/**
	 * @var object	reference to the Joom!Fish manager
	 * @access private
	 */
	var $_joomfishManager=null;

	/**
	 * PHP 4 constructor for the tasker
	 *
	 * @return joomfishTasker
	 */
	function JoomfishControler( ){
		parent::mosAbstractTasker( 'showCPanel' );

		$this->act = mosGetParam( $_REQUEST, 'act', '' );
		$this->task = mosGetParam( $_REQUEST, 'task', '' );
		$this->cid = mosGetParam( $_REQUEST, 'cid', array(0) );
		if (!is_array( $this->cid )) {
			$this->cid = array(0);
		}
		$this->fileCode = mosGetParam( $_REQUEST, 'fileCode', '' );
		$this->_joomfishManager =& $GLOBALS['joomFishManager'];

		$this->registerTask( 'postInstall', 'postInstall' );
		$this->registerTask( 'upgrade', 'upgradeMambelFish' );
		$this->registerTask( 'check', 'showCheckStatusInformation' );
		$this->registerTask( 'copy', 'showCopyInformation' );
	}

	function  showCPanel() {
		$panelStates = array();
		$systemState = $this->_checkSystemState();
		$panelStates['directory_state'] = $systemState['directory_state'];
		$panelStates['directory'] = $systemState['directory'];
		$panelStates['extension_state'] = $systemState['extension_state'];
		$panelStates['extension'] = $systemState['extension'];

		$panelStates['mbfInstall'] = $this->_testOldInstall();
		$panelStates['system'] = $this->_getSystemInfo();

		$contentInfo = array();
		$contentInfo['unpublished'] = $this->_testUnpublisedTranslations();
		//$contentInfo['orphans']  = $this->_testOrphans( );
		//$contentInfo = $this->_testContentElements();

		HTML_joomfish::showCPanel( $panelStates, $contentInfo );
	}

	/**
	 * Generic method to process the back toolbar icon
	 */
	function processBack() {
		switch ($this->act) {
			case 'config_elements':
				$this->showElementOverview();
				break;
		}
	}

	/**
	 * presenting the translation dialog
	 *
	 */
	function showTranslate() {
		global $language_id, $select_language_id, $catid, $contentid, $jfc_id;

		$this->_setupContentElementCache();
		if( $this->_message != '' ) {
			echo "<div class=\"message\">" .$this->_message. "</div>";
		}
		if( !$this->_testSystemBotState() ) {;
		echo "<div style='font-size:16px;font-weight:bold;color:red'>".JText::_('MAMBOT_ERROR')."</div>";
		}


		$this->showTranslationOverview( $select_language_id, $catid );
	}

	function showHelp() {
		if( $this->task == "home" ) {
			$this->_redirect = "index2.php?option=com_joomfish";
			return;
		}

		HTML_joomfish_help::showHelp();
	}

	function showCredits() {
		if( $this->task == "home" ) {
			$this->_redirect = "index2.php?option=com_joomfish";
			return;
		}

		HTML_joomfish_help::showWelcome();
	}

	function showInformation() {
		if( $this->task == "home" ) {
			$this->_redirect = "index2.php?option=com_joomfish";
			return;
		}

		HTML_joomfish::showInformation( $this->fileCode );
	}

	function postInstall () {
		if( $this->task == "home" ) {
			$this->_redirect = "index2.php?option=com_joomfish";
			return;
		}

		HTML_joomfish_help::showPostInstall();
	}

	function showComponentConfig() {
		global $database;

		$languages = array();
		$langDirs = $this->_findDirectories( mosMainFrame::getBasePath() . 'components/com_joomfish/language/' );
		foreach($langDirs as $language ) {
			$languages[] = mosHTML::makeOption( $language, ucfirst( $language ) );
		}

		HTML_joomfish::showComponentConfiguration( $this->_joomfishManager, $languages);
	}

	function saveComponentConfiguration() {
		$this->_joomfishManager->setCfg( 'componentAdminLang' , mosGetParam( $_REQUEST, 'frmComponentAdminLanguage', 'english' ) );
		$this->_joomfishManager->setCfg( 'noTranslation' , mosGetParam( $_REQUEST, 'frmTranslationMode', 0 ) );
		$this->_joomfishManager->setCfg( 'defaultText', mosGetParam( $_REQUEST, 'frmTranslationDefaultText', "" ) );
		$this->_joomfishManager->setCfg( 'storageOfOriginal', mosGetParam( $_REQUEST, 'frmStorageOfOriginal', "md5" ) );
		$this->_joomfishManager->setCfg( 'frontEndPublish' , mosGetParam( $_REQUEST, 'frmPublish',1));
		$this->_joomfishManager->setCfg( 'frontEndPreview' , mosGetParam( $_REQUEST, 'frmFrontEndPreview',1));
		$this->_joomfishManager->setCfg( 'qacaching' , mosGetParam( $_REQUEST, 'qacaching',0));
		$this->_joomfishManager->setCfg( 'qalogging' , mosGetParam( $_REQUEST, 'qalogging',0));
		$frmShowCPanels = mosGetParam( $_REQUEST, 'frmShowCPanels', 0);
		if(is_array($frmShowCPanels)) {
			$total = 0;
			foreach ($frmShowCPanels as $cpanelMod) {
				$total += $cpanelMod;
			}
			$frmShowCPanels = $total;
		}
		$this->_joomfishManager->setCfg( 'showCPanels' , $frmShowCPanels);

		$configSaved = $this->_joomfishManager->saveConfiguration();

		if( $configSaved ) {
			if( $this->task == 'save' ) {
				$this->_redirect = "index2.php?option=com_joomfish&amp;hidemainmenu=0";
			} else {
				$this->_redirect = "index2.php?option=com_joomfish&amp;task=show&amp;act=config_component&amp;hidemainmenu=1";
			}
			$this->_message = JText::_('CONFIG SAVED');
		} else {
			$this->_redirect = "index2.php?option=com_joomfish&amp;task=config_component";
			$this->_message = JText::_('CONFIG_PROBLEMS');
		}
	}



	function showCElementConfig() {
		global $database;

		$this->_setupContentElementCache();
		switch ($this->task) {
			case "uploadfile":
				if( $this->_installContentElement() ) {
					$this->_message = JText::_('Fileupload successful');
				} else {
					$this->_message = JText::_('Fileupload not successful');
				}
				$cElements = $this->_joomfishManager->getContentElements(true);
				HTML_joomfish::showContentElementInstaller( $cElements, $this->_message );
				break;

			default:
				$this->showElementOverview();
				break;
		}
	}

	/**
	 * Installs the uploaded file
	 *
	 */
	function _installContentElement() {
		if (@is_uploaded_file($_FILES["userfile"]["tmp_name"])) {
			$installer = new jfInstaller();
			return $installer->install( $_FILES["userfile"] );
		} else {
			return false;
		}
	}

	/**
	 * method to remove all selected content element files
	 */
	function removeContentElement() {
		if( $this->_deleteContentElement($this->cid[0]) ) {
			$this->_message =JText::_('Elementfile deleted');
		}
		$cElements = $this->_joomfishManager->getContentElements(true);
		HTML_joomfish::showContentElementInstaller( $cElements, $this->_message );
	}

	/**
	 * Method deletes one content element file
	 * @param filename
	 */
	function _deleteContentElement( $filename = null ) {
		global $mosConfig_absolute_path;

		$elementfolder = mosPathName( $mosConfig_absolute_path . '/administrator/components/com_joomfish/contentelements' );
		$filename .= '.xml';

		return @unlink( $elementfolder . $filename );
	}

	/**
	 * shows the language configuration
	 *
	 */
	function showLanguageConfig() {
		global $database;

		if ( $this->task == 'cancel' ) {
			$this->_redirect = "index2.php?option=com_joomfish&hidemainmenu=0";
		} elseif ( $this->task == 'site_config' ) {
			$this->_redirect = "index2.php?option=com_config&hidemainmenu=1";
		} else {

			if( $this->_message != '' ) {
				echo "<div class=\"message\">" .$this->_message. "</div>";
			}

			// 1. read all known languages from the database
			$languages=null;
			$database->setQuery( "SELECT l.*"
			. "\nFROM #__languages AS l"
			. "\nORDER BY l.active desc, l.ordering, l.name"
			);
			$languages = $database->loadObjectList();

			// Read the languages dir to find new installed languages
			$languageBaseDir = mosPathName(mosPathName(mosMainFrame::getBasePath()) . "language");
			$xmlFilesInDir = mosReadDirectory($languageBaseDir,".xml");

			$dirName = $languageBaseDir;
			$activeFiles = null;

			// XML library
			require_once( mosMainFrame::getBasePath() . "/includes/domit/xml_domit_lite_include.php" );

			//mosDebugVar($xmlFilesInDir);
			foreach($xmlFilesInDir as $xmlfile) {
				// Read the file to see if it's a valid template XML file
				$xmlDoc =& new DOMIT_Lite_Document();
				$xmlDoc->resolveErrors( true );
				if (!$xmlDoc->loadXML( $dirName . $xmlfile, false, true )) {
					continue;
				}

				$element = &$xmlDoc->documentElement;

				if ($element->getTagName() != 'mosinstall') {
					continue;
				}
				if ($element->getAttribute( "type" ) != "language") {
					continue;
				}

				$language = $this->_getLanguageFromXML( $xmlfile );
				// Let's see if we find the language already
				$languageFound=false;
				foreach($languages as $dbLang) {
					if ($dbLang->code == $language->code) {
						$languageFound=true;
						break;
					}
				}

				if( !$languageFound ) {
					$languages[] = $language;
				}
			}

			/*elseif (!$languagesSaved) {
			$this->_redirect = "index2.php?option=com_joomfish&task=config_component";
			$this->_message = JText::_('CONFIG_PROBLEMS');
			mosRedirect("index2.php?option=com_joomfish&task=config_component", JText::_('LANG_PROBLEMS') ." - " .$jfLang->getError());
			}*/

			HTML_joomfish::showLanguageConfiguration( $this->_joomfishManager, $languages );
		}
	}

	function saveLanguageConfig() {
		global $database;

		$languagesSaved=false;

		$frmLanguageID = mosGetParam( $_REQUEST, 'frmLanguageID', '' );
		$frmLanguageName = mosGetParam( $_REQUEST, 'frmLanguageName', '' );
		$frmLanguageActive = mosGetParam( $_REQUEST, 'frmLanguageActive', '' );
		$frmLanguageISO = mosGetParam( $_REQUEST, 'frmLanguageISO', '' );
		$frmLanguageShortCode = mosGetParam( $_REQUEST, 'frmLanguageShortCode', '' );
		$frmLanguageCode = mosGetParam( $_REQUEST, 'frmLanguageCode', '' );
		$frmLanguageImage = mosGetParam( $_REQUEST, 'frmLanguageImage', '' );
		$frmLanguageOrder = mosGetParam( $_REQUEST, 'frmLanguageOrder', '' );
		$frmLanguageFallbackCode = mosGetParam( $_REQUEST, 'frmLanguageFallbackCode', '' );


		if( is_array($frmLanguageID) ) {
			$languagesSaved = true;
			for ($i=0; $i<count($frmLanguageID); $i++) {
				$jfLang = new jfLanguage($database);
				$jfLang->id =$frmLanguageID[$i];
				$jfLang->name = $frmLanguageName[$i];

				// The checkbox is only filled when it was active - so we have to check if
				// one box is fitting to your language
				if( isset($frmLanguageActive) ) {
					foreach( $frmLanguageActive as $langid ) {
						if( $langid == $jfLang->id ) {
							$jfLang->active = true;
							break;
						}
					}
				}
				$jfLang->iso = $frmLanguageISO[$i];
				$jfLang->shortcode = $frmLanguageShortCode[$i];
				$jfLang->code = $frmLanguageCode[$i];
				$jfLang->image = $frmLanguageImage[$i];
				$jfLang->ordering = $frmLanguageOrder[$i];
				$jfLang->fallback_code = $frmLanguageFallbackCode[$i];

				if( !$jfLang->store() ) {
					echo "Error: ".$jfLang->getError()."<br />";
					$languagesSaved=false;
				}
			}
		}

		if( $languagesSaved ) {
			if( $this->task == 'save' ) {
				$this->_redirect = "index2.php?option=com_joomfish&hidemainmenu=0";
			} else {
				$this->_redirect = "index2.php?option=com_joomfish&amp;task=show&amp;act=config_language&amp;hidemainmenu=1";
			}
			$this->_message = JText::_('CONFIG SAVED');
		} else {
			$this->_redirect = "index2.php?option=com_joomfish&amp;task=show&amp;act=config_language";
			$this->_message = JText::_('CONFIG_PROBLEMS');
		}
	}


	/**
	 * Translate config settings
	 */
	function saveTranslateConfig(){

		$lang = intval(mosGetParam($_REQUEST,"lang",-1));
		if ($lang>0){

			global $database;
			// confirm this is a valid language
			$database->setQuery( "SELECT l.*"
			. "\nFROM #__languages AS l"
			. "\nWHERE id=$lang");
			$language = null;
			$database->loadObject($language);
			if (!isset($language)){
				echo JText::_("No such language id");
				exit();
			}

			$registry = JRegistry::getInstance("fred","translateconfig");

			$filename = dirname(__FILE__)."/contentelements/mosconfig.ini";
			if (file_exists( $filename ) && $content = @file_get_contents( $filename )) {
				$registry->loadINI($content);
				$itemsToTranslate = $registry->toArray();

				$params = new mosParameters( $language->params );

				foreach ($itemsToTranslate as $item=>$type) {
					// TODO only handles text types!!!
					$params->set($item,mosGetParam($_REQUEST,"transConf".$item,""));
				}
				// param handling
				$saveparams = "";
				if (is_array( $params->toArray() )) {
					$txt = array();
					foreach ( $params->toArray() as $k=>$v) {
						if ($v!=""){
							$txt[] = "$k=$v";
						}
					}
					$saveparams = implode( "\n", $txt );
				}

				$database->setQuery( "UPDATE #__languages SET params='".$saveparams."' WHERE id=$lang");
				if ($database->query()){
					$this->_message = JText::_('Translation saved');
				}
				else {
					$this->_message = JText::_('Translation NOT saved !!');
				}
			}

		}
		else {
			echo JText::_("Bad language id");
			exit();
		}
	}

	/**
	 * Method to remove languages
	 */
	function removeLanguages() {
		global $database;
		$frmLanguageDelete = mosGetParam( $_REQUEST, 'frmLanguageDelete', '' );
		if( $frmLanguageDelete != null && count($frmLanguageDelete)>0) {
			foreach ($frmLanguageDelete as $langid) {
				$jfLang = new jfLanguage($database);
				// This removes all jf_contents for this language as well!
				$jfLang->delete($langid);
				$this->_message = JText::_('DEL_SUCESSFUL');
			}
		}
		$this->showLanguageConfig();
	}

	/**
	 * Translate config settings
	 */
	function translateConfig(){
		// warning if mambot is not enabled for config setting translation
		global $database;
		$database->setQuery( "SELECT * FROM #__mambots WHERE element='jfdatabase.systembot'");
		$database->query();
		$mambot = null;
		$database->loadObject($mambot);
		$botParams = new mosParameters( $mambot->params );
		if ($botParams->get("overwriteGlobalConfig",0)!=1){
			$this->_message.=JText::_("OVERWRITE_GLOBAL_CONFIG_DISABLED");
		}

		$lang = intval(mosGetParam($_REQUEST,"lang",-1));
		if ($lang>0){

			if( $this->_message != '' ) {
				echo "<div class=\"message\">" .$this->_message. "</div>";
			}

			global $database;
			// confirm this is a valid language
			$database->setQuery( "SELECT l.*"
			. "\nFROM #__languages AS l"
			. "\nWHERE id=$lang");
			$language = null;
			$database->loadObject($language);
			if (!isset($language)){
				echo JText::_("No such language id");
				exit();
			}

			$registry = JRegistry::getInstance("fred","translateconfig");

			$filename = dirname(__FILE__)."/contentelements/mosconfig.ini";
			if (file_exists( $filename ) && $content = @file_get_contents( $filename )) {
				$registry->loadINI($content);
				$itemsToTranslate = $registry->toArray();
				HTML_joomfish::translateConfig( $itemsToTranslate, $language );
			}
			else{
				// mic
				echo JText::_( 'FILE MOSCONFIGINI MISSING' );
			}

		}
		else {
			echo JText::_("Bad language id");
			exit();
		}
	}

	/**
	 * Provides a basic upgrade functionallity based
	 */
	function showUpgrade() {
		$upgradeSucessful = false;
		$upgradeDone = $this->_joomfishManager->getCfg( 'jfupgradeDone' );

		$lists = array();
		$lists['confirmDelete'] = mosGetParam( $_REQUEST, 'confirmDelete', 0 );
		$lists['backupTables'] = mosGetParam( $_REQUEST, 'backupTables', 1 );
		$lists['renameTables'] = mosGetParam( $_REQUEST, 'renameTables', 1 );

		HTML_joomfish::showUpgradeInstall( $this->_joomfishManager, $upgradeSucessful, $upgradeDone, $lists );
	}

	/**
	 * Method to execute the MambelFish upgrade
	 */
	function upgradeMambelFish() {
		$upgradeSucessful = false;
		$upgradeDone = $this->_joomfishManager->getCfg( 'mbfupgradeDone', '0' );

		$lists = array();
		$lists['confirmDelete'] = mosGetParam( $_REQUEST, 'confirmDelete', 0 );
		$lists['backupTables'] = mosGetParam( $_REQUEST, 'backupTables', 1 );
		$lists['renameTables'] = mosGetParam( $_REQUEST, 'renameTables', 1 );

		if( !$lists [ 'confirmDelete'] ) {
			$this->_message = JText::_('UPGRADE_ERROR_CONFIRM');
			$this->_redirect = "index2.php?option=com_joomfish&amp;task=show&amp;act=upgrade_install&amp;hidemainmenu=1";
		} else {
			$summary = $this->_upgradeInstallation( $lists['backupTables'], $lists['renameTables'] );
			if( !$summary['state'] ) {
				$upgradeSucessful = false;
				$upgradeDone = 1;
				$summary['message'] = JText::_('UPGRADE_ERROR_UPGRADE');
				$this->_message = JText::_('UPGRADE_ERROR_UPGRADE');
				$lists['summary'] = $summary;
			} else {
				$upgradeSucessful = true;
				$upgradeDone = 1;
				$this->_joomfishManager->setCfg( 'mbfupgradeDone', $upgradeDone );
				$this->_joomfishManager->saveConfiguration();
				$lists['summary'] = $summary;
			}

			HTML_joomfish::showUpgradeInstall( $this->_joomfishManager, $upgradeSucessful, $upgradeDone, $lists );
		}
	}

	/**
	 * Helperfunction to retriev the language information from the XML files
	 */
	function _getLanguageFromXML( $xmlfile ) {
		global $database;

		// Read the language dir to find languages
		$languageBaseDir = mosPathName(mosPathName(mosMainFrame::getBasePath()) . "language");
		$dirName = $languageBaseDir;

		// XML library
		require_once( mosMainFrame::getBasePath() . "/includes/domit/xml_domit_lite_include.php" );

		$xmlDoc =& new DOMIT_Lite_Document();
		$xmlDoc->resolveErrors( true );
		if ($xmlDoc->loadXML( $dirName . $xmlfile, false, true )) {
			$lang = new jfLanguage($database);
			$lang->code = substr($xmlfile,0,-4);
			$element = &$xmlDoc->getElementsByPath('name', 1);
			$lang->name = $element->getText();
			$lang->active=false;
		}
		return $lang;
	}

	/** Presentation of the content element list
	 */
	function showElementOverview() {
		global $database, $mainframe;

		$limit = $mainframe->getUserStateFromRequest( "viewlistlimit", 'limit', 10 );
		$limitstart = $mainframe->getUserStateFromRequest( "view{com_joomfish}limitstart", 'limitstart', 0 );
		$total=count($this->_joomfishManager->getContentElements());

		require_once( mosMainFrame::getBasePath() . "/administrator/includes/pageNavigation.php");
		$pageNav = new mosPageNav( $total, $limitstart, $limit );

		HTML_joomfish::showElementOverview( $this->_joomfishManager, $pageNav );
	}

	/** Detailinformation about one specific content element */
	function showElementConfiguration( $id ) {
		global $database, $mainframe;

		HTML_joomfish::showElementConfiguration( $this->_joomfishManager, $id );
	}

	/**
	 * Method to install content element files
	 *
	 */
	function showContentElementsInstaller() {
		$cElements = $this->_joomfishManager->getContentElements(true);
		HTML_joomfish::showContentElementInstaller( $cElements, $this->_message );
	}


	/** Presentation of the content's that must be translated
	 */
	function showTranslationOverview( $language_id, $catid) {
		global $database, $mainframe;

		$limit = $mainframe->getUserStateFromRequest( "viewlistlimit", 'limit', 10 );
		$limitstart = $mainframe->getUserStateFromRequest( "view{com_joomfish}limitstart", 'limitstart', 0 );
		$search = $mainframe->getUserStateFromRequest( "search{com_joomfish}", 'search', '' );
		$search = $database->getEscaped( trim( strtolower( $search ) ) );

		// Build up the rows for the table
		$rows=null;
		$total=0;
		$filterHTML=array();
		if( $language_id != -1 && isset($catid) && $catid!="" ) {
			$contentElement = $this->_joomfishManager->getContentElement( $catid );
			$tranFilters = getTranslationFilters($catid,$contentElement);

			$database->setQuery( $contentElement->createContentSQL( $language_id, null, $limitstart, $limit,$tranFilters ) );
			$rows = $database->loadObjectList();
			if ($database->getErrorNum()) {
				echo $database->stderr();
				return false;
			}

			$total = $contentElement->countReferences($language_id, $tranFilters);

			// Manipulation of result based on further information
			for( $i=0; $i<count($rows); $i++ ) {
				$contentObject = new ContentObject( $language_id, $contentElement );
				$contentObject->readFromRow( $rows[$i] );
				$rows[$i] = $contentObject;
			}

			foreach ($tranFilters as $tranFilter){
				$afilterHTML=$tranFilter->_createFilterHTML();
				if (isset($afilterHTML)) $filterHTML[$tranFilter->filterType] = $afilterHTML;
			}

		}

		require_once( mosMainFrame::getBasePath() . "/administrator/includes/pageNavigation.php");
		$pageNav = new mosPageNav( $total, $limitstart, $limit );

		// get list of active languages
		$langOptions[] = mosHTML::makeOption( '-1', JText::_('Select Language') );
		$langOptions[] = mosHTML::makeOption( 'NULL', JText::_('Select no Translation'));

		$langActive = $this->_joomfishManager->getLanguages( false );		// all languages even non active once

		if ( count($langActive)>0 ) {
			foreach( $langActive as $language )
			{
				$langOptions[] = mosHTML::makeOption( $language->id, $language->name );
			}
		}
		$langlist = mosHTML::selectList( $langOptions, 'select_language_id', 'class="inputbox" size="1" onchange="document.adminForm.submit();"', 'value', 'text', $language_id );

		// get list of element names
		$elementNames[] = mosHTML::makeOption( '', JText::_('Please select') );
		//$elementNames[] = mosHTML::makeOption( '-1', '- All Content elements' );
		$elements = $this->_joomfishManager->getContentElements();
		foreach( $elements as $key => $element )
		{
			$elementNames[] = mosHTML::makeOption( $key, $element->Name );
		}
		$clist = mosHTML::selectList( $elementNames, 'catid', 'class="inputbox" size="1" onchange="document.adminForm.submit();"', 'value', 'text', $catid );
		HTML_joomfish::showTranslationOverview( $rows, $search, $pageNav, $langlist, $clist, $catid ,$language_id,$filterHTML );
	}

	/** Details of one content for translation
	 */
	function editTranslation( $translation_id, $language_id, $catid, $contentid, $select_language_id ) {
		global $database, $mainframe, $my,$mosConfig_live_site;
		$actContentObject=null;

		if( $this->_message != '' ) {
			echo "<div class=\"message\">" .$this->_message. "</div>";
		}

		if( isset($catid) && $catid!="" ) {
			$contentElement = $this->_joomfishManager->getContentElement( $catid );
			$actContentObject = new ContentObject( $language_id, $contentElement );
			$actContentObject->loadFromContentID( $contentid );
		}

		// fail if checked out not by 'me'
		if ($actContentObject->checked_out && $actContentObject->checked_out <> $my->id) {
			mosRedirect( "index2.php?option=option=com_joomfish&task=translate",
			"The content item $actContentObject->title is currently being edited by another administrator" );
		}

		// get list of active languages
		$langOptions[] = mosHTML::makeOption( 'NULL', JText::_('Select no translation') );

		$langActive = $this->_joomfishManager->getLanguages( false );		// all languages even non active once

		if ( count($langActive)>0 ) {
			foreach( $langActive as $language )
			{
				$langOptions[] = mosHTML::makeOption( $language->id, $language->name );
			}
		}
		$confirm="";
		if ($actContentObject->language_id!=0){
			$confirm="onchange=\"confirmChangeLanguage('".$actContentObject->language."','".$actContentObject->language_id."')\"";
		}

		$langlist = mosHTML::selectList( $langOptions, 'language_id', 'class="inputbox" size="1" '.$confirm, 'value', 'text', $actContentObject->language_id );

		// get existing filters so I can remember them!
		$tranFilters = getTranslationFilters($catid,$contentElement);

		HTML_joomfish::showTranslation( $actContentObject, $langlist, $catid, $select_language_id , $tranFilters );
	}

	/** Saves the information of one translation
	 */
	function saveTranslation( $language_id, $catid, $id, $jfc_id ) {
		global $database, $mainframe, $select_language_id;
		$actContentObject=null;

		if( isset($catid) && $catid!="" ) {
			$contentElement = $this->_joomfishManager->getContentElement( $catid );
			$actContentObject = new ContentObject( $language_id, $contentElement );

			// get's the config settings on how to store original files
			$storeOriginalText = ($this->_joomfishManager->getCfg('storageOfOriginal') == 'md5') ? false : true;
			$actContentObject->bind( $_POST, '', '', true,  $storeOriginalText);
			$actContentObject->store();
		}
		$this->_message = JText::_('Translation saved');
	}

	/**
	 * method to remove a translation
	 */
	function removeTranslation() {
		global $language_id, $select_language_id, $catid, $contentid, $jfc_id;
		$this->_removeTranslation( $catid, $this->cid );

		$this->showTranslationOverview($language_id, $catid);
	}

	/** Presentation of translations that have been orphaned
	 */
	function showOrphanOverview( $language_id, $catid) {
		global $database, $mainframe;

		$limit = $mainframe->getUserStateFromRequest( "viewlistlimit", 'limit', 10 );
		$limitstart = $mainframe->getUserStateFromRequest( "view{com_joomfish}limitstart", 'limitstart', 0 );
		$search = $mainframe->getUserStateFromRequest( "search{com_joomfish}", 'search', '' );
		$search = $database->getEscaped( trim( strtolower( $search ) ) );

		$tranFilters=array();
		$filterHTML=array();

		// Build up the rows for the table
		$rows=null;
		$total=0;
		if( isset($catid) && $catid!="" ) {
			$contentElement = $this->_joomfishManager->getContentElement( $catid );

			$database->setQuery( $contentElement->createOrphanSQL( $language_id, null, $limitstart, $limit,$tranFilters ) );
			$rows = $database->loadObjectList();
			if ($database->getErrorNum()) {
				echo $database->stderr();
				return false;
			}

			$total = count($rows);

			for( $i=0; $i<count($rows); $i++ ) {
				//$contentObject = new ContentObject( $language_id, $contentElement );
				//$contentObject->readFromRow( $row );
				//$rows[$i] = $contentObject ;
				$rows[$i]->state=null;
				$rows[$i]->title="original missing";
				$rows[$i]->checked_out=false;
			}
		}

		require_once( mosMainFrame::getBasePath() . "/administrator/includes/pageNavigation.php");
		$pageNav = new mosPageNav( $total, $limitstart, $limit );

		// get list of active languages
		$langlist = "";

		$langOptions[] = mosHTML::makeOption( '-1', JText::_('Select language') );
		//$langOptions[] = mosHTML::makeOption( '-2', JText::_('SELECT_NOTRANSLATION') );

		$langActive = $this->_joomfishManager->getLanguages( false );		// all languages even non active once

		if ( count($langActive)>0 ) {
			foreach( $langActive as $language )
			{
				$langOptions[] = mosHTML::makeOption( $language->id, $language->name );
			}
		}
		$langlist = mosHTML::selectList( $langOptions, 'select_language_id', 'class="inputbox" size="1" onchange="document.adminForm.submit();"', 'value', 'text', $language_id );

		// get list of element names
		$elementNames[] = mosHTML::makeOption( '', JText::_('PLEASE SELECT') );
		//$elementNames[] = mosHTML::makeOption( '-1', '- All Content elements' );
		$elements = $this->_joomfishManager->getContentElements();
		foreach( $elements as $key => $element )
		{
			$elementNames[] = mosHTML::makeOption( $key, $element->Name );
		}
		$clist = mosHTML::selectList( $elementNames, 'catid', 'class="inputbox" size="1" onchange="document.adminForm.submit();"', 'value', 'text', $catid );
		HTML_joomfish::showOrphanOverview( $rows, $search, $pageNav, $langlist, $clist, $catid ,$language_id,$filterHTML );
	}

	/**
	 * method to show orphan translation details
	 *
	 * @param unknown_type $jfc_id
	 * @param unknown_type $contentid
	 * @param unknown_type $tablename
	 * @param unknown_type $lang
	 */
	function showOrphanDetail( $jfc_id, $contentid, $tablename, $lang){
		global  $database;

		// read details of orphan translation
		//$sql = "SELECT * FROM #__jf_content WHERE id=$mbfc_id AND reference_id=$contentid AND reference_table='".$tablename."'";
		$sql = "SELECT * FROM #__jf_content WHERE reference_id=$contentid AND language_id='".$lang."' AND reference_table='".$tablename."'";	//print "sql = $sql<br>contentid=$contentid , mbfc_id= $mbfc_id from $tablename<br>";
		$database->setQuery($sql);
		$rows = null;
		$rows=$database->loadObjectList();
		//print_r($row);
		HTML_joomfish::showOrphan($rows, $tablename);
	}

	/**
	 * Reload all translations and publish/unpublish them
	 */
	function publishTranslation( $catid, $cid, $publish ) {
		foreach( $cid as $cid_row ) {
			list($translation_id, $contentid, $language_id) = explode('|', $cid_row);

			$contentElement = $this->_joomfishManager->getContentElement( $catid );
			$actContentObject = new ContentObject( $language_id, $contentElement );
			$actContentObject->loadFromContentID( $contentid );
			if( $actContentObject->state>=0 ) {
				$actContentObject->setPublished($publish);
				$actContentObject->store();
				$this->_message = ($publish ? JText::_('Translation published') : JText::_('Translation unpublished') );
			}
		}
	}

	/** This method prepares the managment overview of the system
	 * Within the view it is possible to execute several management functions for the Joom!Fish
	 */
	function showManagementOverview( $language_id, $catid) {
		global $database, $mainframe;

		if( !$this->_testSystemBotState() ) {;
		echo "<div style='font-size:16px;font-weight:bold;color:red'>".JText::_('MAMBOT_ERROR')."</div>";
		}

		$type = mosGetParam( $_REQUEST, 'type', '' );


		HTML_joomfish::showManagementOverview($type);
	}

	/**
	 * This method performce a general status check for various types
	 *
	 */
	function showCheckStatusInformation() {
		global $mainframe;

		$type = mosGetParam( $_REQUEST, 'type', '' );
		$phase = intval( mosGetParam( $_REQUEST, 'phase', 1 ) );
		$statecheck_i = intval( mosGetParam( $_REQUEST, 'statecheck_i', -1 ) );
		$htmlResult = JText::_('MANAGEMENT_INTRO');
		$link = '';

		switch ($type) {
			case 'translation_status':
				$message = '';
				$translationStatus = $mainframe->getUserState('translationState', 'translationState', array());
				$translationStatus = $this->_testTranslationStatus($translationStatus, $phase, $statecheck_i, $message);
				$mainframe->setUserState('translationState', $translationStatus );

				$htmlResult = HTML_joomfish::renderTranslationStatusTable($translationStatus, $message);
				if( $phase<=3 ) {
					$link = 'index3.php?option=com_joomfish&task=check&act=manage&type=translation_status&phase=' .$phase;

					if( $statecheck_i > -1) {
						$link .= '&statecheck_i='.$statecheck_i;
					}
				} else {
					$mainframe->setUserState('translationState', null );
				}
				break;

			case 'original_status':
				$message = '';
				$originalStatus = $mainframe->getUserState('originalStatus', 'originalStatus', array());
				$langCodes = array();
				$languages = $this->_joomfishManager->getLanguages(false);
				foreach ($languages as $lang) {
					$langCodes[] = $lang->getLanguageCode();
				}

				$originalStatus = $this->_testOriginalStatus($originalStatus, $phase, $statecheck_i, $message, $languages);
				$mainframe->setUserState('originalStatus', $originalStatus );
				$htmlResult = HTML_joomfish::renderOriginalStatusTable($originalStatus, $message, $langCodes);

				if( $phase<=2 ) {
					$link = 'index3.php?option=com_joomfish&task=check&act=manage&type=original_status&phase=' .$phase;

					if( $statecheck_i > -1) {
						$link .= '&statecheck_i='.$statecheck_i;
					}
				} else {
					$mainframe->setUserState('originalStatus', null );
				}
				break;
		}
		HTML_joomfish::showManagementResult( $htmlResult, $link );
	}

	/**
	 * this method creates the iframe information for the copy process
	 *
	 */
	function showCopyInformation () {
		global $mainframe;

		$type = mosGetParam( $_REQUEST, 'type', '' );
		$phase = intval( mosGetParam( $_REQUEST, 'phase', 1 ) );
		$state_catid = mosGetParam( $_REQUEST, 'state_catid', '' );
		$language_id = intval( mosGetParam( $_REQUEST, 'language_id', null ) );
		$overwrite = intval( mosGetParam($_REQUEST, 'overwrite', 0) );
		$htmlResult = JText::_('MANAGEMENT_INTRO');
		$link = '';

		$languages = $this->_joomfishManager->getLanguages( false );		// all languages even non active once
		$langOptions = array();
		$langOptions[] = mosHTML::makeOption( -1, JText::_('Do not copy') );

		if ( count($languages)>0 ) {
			foreach( $languages as $language )
			{
				$langOptions[] = mosHTML::makeOption( $language->id, $language->name );
			}
		}
		$langlist = mosHTML::selectList( $langOptions, 'select_language', 'id="select_language" class="inputbox" size="1"', 'value', 'text', -1 );

		switch ($type) {
			case 'original_language':
				$message = '';
				$original2languageInfo = $mainframe->getUserState('original2languageInfo', 'original2languageInfo', array());
				$original2languageInfo = $this->_copyOriginalToLanguage($original2languageInfo, $phase, $state_catid, $language_id, $overwrite, $message);
				$mainframe->setUserState('original2languageInfo', $original2languageInfo );

				if($phase == 1) {
					$htmlResult = HTML_joomfish::renderCopyInformation($original2languageInfo, $message, $langlist);
				} elseif( $phase == 2 || $phase == 3 ) {
					$htmlResult = HTML_joomfish::renderCopyProcess($original2languageInfo, $message);
					$link = 'index3.php?option=com_joomfish&task=copy&act=manage&type=original_language&phase=' .$phase. '&language_id=' .$language_id. '&state_catid=' .$state_catid. '&overwrite=' .$overwrite;
				} else {
					$htmlResult = HTML_joomfish::renderCopyProcess($original2languageInfo, $message);
					$mainframe->setUserState('original2languageInfo', null );
				}
				break;
		}
		HTML_joomfish::showManagementResult( $htmlResult, $link );
	}

	/**
	 * Deletes the selected translations (only the translations of course)
	 */
	function _removeTranslation( $catid, $cid ) {
		global $database;
		foreach( $cid as $cid_row ) {
			list($translationid, $contentid, $language_id) = explode('|', $cid_row);

			$contentElement = $this->_joomfishManager->getContentElement( $catid );
			$contentTable = $contentElement->getTableName();
			$contentid= intval($contentid);
			$translationid = intval($translationid);

			// safety check -- complete overkill but better to be safe than sorry

			// get the translation details
			$translation = new jfContent($database);
			$translation->load($translationid);

			if (!isset($translation))		{
				JText::sprintf('NO_SUCH_TRANSLATION', $translationid);
				continue;
			}

			// make sure translation matches the one we wanted
			if ($contentid != $translation->reference_id){
				echo JText::_('Something dodgy going on here');
				continue;
			}

			// ??? This line doesn't make sense!
			$sql= "SELECT * from #__$contentTable WHERE id=".$translationid;
			$database->setQuery($sql);
			$rows = $database->loadObjectList("");
			if (count($rows)>0) {
				echo "ID $contentid is not an orphan translation - it has not been deleted<br/>";
				continue;
			}
			// ???

			$sql= "DELETE from #__jf_content WHERE reference_table='$catid' and language_id=$language_id and reference_id=$contentid";
			$database->setQuery($sql);
			$database->query();
			if( $database->getErrorNum() != 0 ) {
				echo JText::_('Something dodgy going on here');
				echo $database->getErrorMsg();
				continue;
			}
		}
	}

	/**
	 * Sets up ContentElement Cache - mainly used for data to determine primary key id for tablenames ( and for
	 * future use to allow tables to be dropped from translation even if contentelements are installed )
	 */
	function _setupContentElementCache()
	{

		global $database;
		// Make usre table exists otherwise create it.
		$database->setQuery( "CREATE TABLE IF NOT EXISTS `#__jf_tableinfo` ( `id` int(11) NOT NULL auto_increment, `joomlatablename` varchar(100) NOT NULL default '',  `tablepkID`  varchar(100) NOT NULL default '', PRIMARY KEY (`id`)) TYPE=MyISAM");
		$database->query();
		// clear out existing data
		$database->setQuery( "DELETE FROM `#__jf_tableinfo`");
		$database->query();
		$contentElements = $this->_joomfishManager->getContentElements();
		$sql = "INSERT INTO `#__jf_tableinfo` (joomlatablename,tablepkID) VALUES ";
		$firstTime = true;
		foreach ($contentElements as $contentElement){
			$tablename = $contentElement->getTableName();
			// populate cache
			include_once( mosMainFrame::getBasePath().'/components/com_joomfish/includes/joomfish.class.php' );
			JoomFish::_contentElementFields($tablename);
			$refId = $contentElement->getReferenceID();
			$sql .= $firstTime?"":",";
			$sql .= " ('".$tablename."', '".$refId."')";
			$firstTime = false;
		}

		$database->setQuery( $sql);
		$database->query();

	}

	/**
	 * This method checks the different system states based on the definition in the component XML file.
	 * @return array with rows of the different component states
	 *
	 */
	function _checkSystemState() {
		global $database, $mosConfig_Livesite;

		require_once( mosMainFrame::getBasePath() . "/includes/domit/xml_domit_lite_include.php" );
		$checkResult = array();

		// Read the file to see if it's a valid template XML file
		$xmlDoc =& new DOMIT_Lite_Document();
		$xmlDoc->resolveErrors( true );
		$xmlfile = JOOMFISH_ADMINPATH .DS. 'joomfish.xml';
		if (!$xmlDoc->loadXML( $xmlfile, false, true )) {
			return $checkResult;
		}

		$element = &$xmlDoc->documentElement;

		if ($element->getTagName() != 'mosinstall') {
			return $checkResult;
		}
		if ($element->getAttribute( "type" ) != "component") {
			return $checkResult;
		}
		$checkElements = $xmlDoc->getElementsByPath('check', 1);
		if (!isset($checkElements) || !$checkElements->hasChildNodes()){
			return $checkResult;
		}

		// Default values of different master states
		$checkResult['directory_state'] = true;
		$checkResult['extension_state'] = true;

		foreach ($checkElements->childNodes as $child){
			$type = $child->nodeName;
			$check = new stdClass();
			switch ($type) {
				case "directory":
					$check->description = $child->getText();
					$check->result = is_writable(mosMainFrame::getBasePath() .DS. $check->description) ? true : false;
					$check->resultText = $check->result ? JText::_('writable') : JText::_('not writable');
					$check->link = '';
					$checkResult[$type][] = $check;
					$checkResult[$type. '_state'] = $checkResult[$type. '_state'] & $check->result;
					break;

				case "extension":
					$check->description = JText::_($child->getAttribute('name'));
					$table = $child->getAttribute('type');
					$field = $child->getAttribute('field');
					$value = $child->getAttribute('value');
					$condition = $child->getText();

					$sql = "SELECT $field, id FROM #__$table WHERE $condition";
					$database->setQuery($sql);
					$resultValue = $database->loadRow();

					if( $resultValue != null ) {
						$check->result = ($value == $resultValue[0]) ? true : false;
						$check->resultText = $check->result ? JText::_($field) : JText::_('un'.$field);

						$check->link = 'index2.php?option=com_'.$table.'&amp;client=&amp;task=editA&amp;hidemainmenu=1&amp;id='.$resultValue[1];
					} else {
						$check->result = false;
						$check->resultText = JText::_('not installed');

						$check->link = '';
					}

					$checkResult[$type][] = $check;
					$checkResult[$type. '_state'] = $checkResult[$type. '_state'] & $check->result;
					break;
			}
		}
		return $checkResult;
	}

	/**
	 * Testing state of the system bot
	 *
	 */
	function _testSystemBotState()
	{
		global $database;
		$botState = false;

		$database->setQuery( "SELECT * FROM #__mambots WHERE element='jfdatabase.systembot'");
		$database->query();
		$database->loadObject($mambot);
		if ($mambot != null && $mambot->published == "1") {
			$botState = $mambot->id;
		}
		return $botState;
	}

	/**
	 * Testing state of the system bot
	 *
	 */
	function _testSearchBotState()
	{
		global $database;
		$botState = false;

		$database->setQuery( "SELECT * FROM #__mambots WHERE element='jfcontent.searchbot'");
		$database->query();
		$database->loadObject($mambot);
		if ($mambot != null && $mambot->published == "1") {
			$botState = $mambot->id;
		}
		return $botState;
	}

	/**
	 * Testing state of the system bot
	 *
	 */
	function _testModuleState()
	{
		global $database;
		$moduleState = false;

		$database->setQuery( "SELECT * FROM #__modules WHERE module='mod_jflanguageselection'");
		$database->query();
		$database->loadObject($module);
		if ($module != null && $module->published == "1") {
			$moduleState = $module->id;
		}
		return $moduleState;
	}

	/**
	 * Testing if old installation is found and upgraded?
	 * @return int		0 := component not installed, 1 := installed but not upgraded, 2 := installed and upgraded
	 */
	function _testOldInstall()
	{
		global $database;
		$oldInstall = 0;

		$database->setQuery( "SHOW TABLES LIKE '%mbf_%'" );
		$database->query();
		$rows = $database->loadResultArray();
		foreach ($rows as $row) {
			if( ereg( 'mbf_content', $row ) ) {
				$oldInstall = 1;
				break;
			}
		}

		if( $oldInstall == 1 && $this->_joomfishManager->getCfg( 'mbfupgradeDone' ) ) {
			$oldInstall = 2;
		}

		return $oldInstall;
	}

	/**
	 * This method gethers certain information of the system which can be used for presenting
	 * @return array with inforation about the system
	 */
	function _getSystemInfo() {
		global $database;

		$database->setQuery( 'SELECT count(*) FROM #__jf_content');
		$database->query();
		$translations = $database->loadResult();

		$res = array( 'translations' => $translations );
		return $res;
	}

	/**
	 * Start of a function to obtain overview summary of orphan translations
	 *
	 * @return array of orphan tables or nothing if no orphans found
	 */
	function _testOrphans( ) {
		global $database, $mainframe, $mosConfig_dbprefix;
		$orphans = array();
		$tranFilters=array();
		$filterHTML=array();

		$query = "select distinct CONCAT('".$mosConfig_dbprefix."',reference_table) from #__jf_content";
		$database->setQuery( $query );
		$tablesWithTranslations = $database->loadResultArray();

		$query = "SHOW TABLES";
		$database->setQuery( $query );
		$tables = $database->loadResultArray();

		$allContentElements = $this->_joomfishManager->getContentElements();
		foreach ($allContentElements as $catid=>$ce){
			$tablename = $mosConfig_dbprefix.$ce->referenceInformation["tablename"];
			if (in_array($tablename,$tables) &&
			in_array($tablename,$tablesWithTranslations)){
				$database->setQuery( $ce->createOrphanSQL( -1, null, -1, -1,$tranFilters ) );
				$rows = $database->loadObjectList();
				if ($database->getErrorNum()) {
					$this->_message = $database->stderr();
					return false;
				}

				$total = count($rows);
				if ($total>0) {
					$orphans[] = array( 'catid' => $catid, 'name' => $ce->Name, 'total' => $total);
				}
			}
		}

		foreach ($tablesWithTranslations as $twv) {
			if (!in_array($twv,$tables)) {
				$this->_message = "Translations exists for table <b>$twv</b> which is no longer in the database<br/>";
			}
		}
		return $orphans;
	}

	/**
	 * This method tests for the content elements and their original/translation status
	 * It will return an array listing all content element names including information about how may originals
	 *
	 * @param array 	$originalStatus	array with original state values if exist
	 * @param int		$phase	which phase of the status check
	 * @param string	$statecheck_i	running row number starting with -1!
	 * @param string	$message	system message
	 * @param array		$languages	array of availabe languages
	 * @return array	with resulting rows
	 */
	function _testOriginalStatus($originalStatus, &$phase, &$statecheck_i, &$message, $languages) {
		global $database, $mosConfig_dbprefix;
		$tranFilters=array();
		$filterHTML=array();
		$sql = '';

		switch ($phase) {
			case 1:
				$originalStatus = array();

				$sql = "select distinct CONCAT('".$mosConfig_dbprefix."',reference_table) from #__jf_content";
				$database->setQuery( $sql );
				$tablesWithTranslations = $database->loadResultArray();

				$sql = "SHOW TABLES";
				$database->setQuery( $sql );
				$tables = $database->loadResultArray();

				$allContentElements = $this->_joomfishManager->getContentElements();

				foreach ($allContentElements as $catid=>$ce){
					$ceInfo = array();
					$ceInfo['name'] = $ce->Name;
					$ceInfo['catid'] = $catid;
					$ceInfo['total'] = '??';
					$ceInfo['missing_table'] = false;
					$ceInfo['message'] = '';

					$tablename = $mosConfig_dbprefix.$ce->referenceInformation["tablename"];
					if (in_array($tablename,$tables)){
						// get total count of table entries
						$database->setQuery( 'SELECT COUNT(*) FROM ' .$tablename );
						$ceInfo['total'] = $database->loadResult();

						if( in_array($tablename,$tablesWithTranslations) ) {
							// get orphans
							$database->setQuery( $ce->createOrphanSQL( -1, null, -1, -1,$tranFilters ) );
							$rows = $database->loadObjectList();
							if ($database->getErrorNum()) {
								$this->_message = $database->stderr();
								return false;
							}
							$ceInfo['orphans'] = count($rows);

							// get number of valid translations
							$ceInfo['valid'] = 0;


							// get number of outdated translations
							$ceInfo['outdated'] = $ceInfo['total'] - $ceInfo['orphans'] - $ceInfo['valid'];

						}else {
							$ceInfo['orphans'] = '0';
						}
					} elseif (!in_array($tablename, $tables)) {
						$ceInfo['missing_table'] = true;
						$ceInfo['message'] = JText::sprintf(TABLE_DOES_NOT_EXIST, $tablename );
					}
					$originalStatus[] = $ceInfo;
				}
				$message = JText::sprintf('ORIGINAL_PHASE1_CHECK', '');
				$phase ++;
				$statecheck_i = 0;
				break;

			case 2:
				if( is_array($originalStatus) && count ($originalStatus)>0 ) {
					if( $statecheck_i>=0 && $statecheck_i<count($originalStatus)) {
						$stateRow =& $originalStatus[$statecheck_i];

						foreach ($languages as $lang) {
							$sql = "SELECT * FROM #__jf_content as jfc" .
							"\n  WHERE jfc.language_id=" .$lang->id .
							"\n    AND jfc.reference_table='" .$stateRow['catid'] ."'".
							"\n    AND jfc.published=1" .
							"\n	 GROUP BY reference_id";
							$database->setQuery($sql);
							$rows = $database->loadRowList();
							$key = 'langentry_' .$lang->getLanguageCode();
							$stateRow[$key] = count($rows);
						}
					}

					if ($statecheck_i<count($originalStatus)-1) {
						$statecheck_i ++;
						$message = JText::sprintf('ORIGINAL_PHASE1_CHECK', ' ('. $originalStatus[$statecheck_i]['name'] .')');
					} else {
						$message = JText::_('ORIGINAL_PHASE2_CHECK');
						$phase = 3;	// exit
					}
				} else {
					$phase = 3; // exit
					$message = JText::_('ORIGINAL_PHASE2_CHECK');
				}
				break;
		}

		return $originalStatus;
	}

	/**
	 * This method checks the translation status
	 * The process follows goes through out all existing translations and checks their individual status.
	 * The output is a summary information based grouped by content element files and the languages
	 *
	 * @param array 	$translationStatus	array with translation state values
	 * @param int		$phase	which phase of the status check
	 * @param string	$statecheck_i	running row number starting with -1!
	 * @param string	$message	system message
	 */
	function _testTranslationStatus( $translationStatus, &$phase, &$statecheck_i, &$message ) {
		global $database;

		$sql = '';

		switch ($phase) {
			case 1:
				$sql = "SELECT jfc.reference_table, jfc.language_id, jfl.name AS language" .
				"\n FROM #__jf_content AS jfc" .
				"\n JOIN #__languages AS jfl ON jfc.language_id = jfl.id" .
				"\n GROUP BY jfc.reference_table, jfc.language_id";
				$database->setQuery($sql);
				$rows = $database->loadObjectList();

				$translationStatus = array();
				if( is_array($rows) && count($rows)>0 ) {
					foreach ($rows as $row) {
						$status = array();
						$contentElement = $this->_joomfishManager->getContentElement( $row->reference_table );
						$status['content'] = $contentElement->Name;
						$status['catid'] = $row->reference_table;
						$status['language_id'] = $row->language_id;
						$status['language'] = $row->language;

						$status['total'] = '';
						$status['state_valid'] = '';
						$status['state_unvalid'] = '';
						$status['state_missing'] = '';
						$status['state'] = '';
						$status['published'] = '';

						$sql = "SELECT * FROM #__jf_content" .
						"\n WHERE reference_table='" .$row->reference_table. "'" .
						"\n   AND language_id=" .$row->language_id .
						"\n GROUP BY reference_id";
						$database->setQuery($sql);
						$totalrows = $database->loadRowList();
						if( $totalrows = $database->loadRowList() ) {
							$status['total'] = count($totalrows);
						}

						$translationStatus[] = $status;
					}

					$message = JText::_('TRANSLATION_PHASE1_GENERALCHECK');
					$phase ++;
				} else {
					$message = JText::_('No Translation available');
					$phase = 4;		// exit
				}
				break;

			case 2:
				if( is_array($translationStatus) && count ($translationStatus)>0 ) {

					for ($i=0; $i<count($translationStatus); $i++) {
						$stateRow =& $translationStatus[$i];
						$sql = "select *" .
						"\n from #__jf_content as jfc" .
						"\n where published=1" .
						"\n and reference_table='" .$stateRow['catid']. "'".
						"\n and language_id=" .$stateRow['language_id'].
						"\n group by reference_ID";

						$database->setQuery($sql);
						if( $rows = $database->loadRowList() ) {
							$stateRow['published'] = count($rows);
						} else {
							$stateRow['published'] = 0;
						}
					}
				}

				$message = JText::sprintf('TRANSLATION_PHASE2_PUBLISHEDCHECK', '');
				$phase ++;
				break;

			case 3:
				if( is_array($translationStatus) && count ($translationStatus)>0 ) {
					if( $statecheck_i>=0 && $statecheck_i<count($translationStatus)) {
						$stateRow =& $translationStatus[$statecheck_i];

						$contentElement = $this->_joomfishManager->getContentElement( $stateRow['catid'] );
						$filters = array();

						// trap missing content element files
						if (is_null($contentElement)){
							$message = JText::_('TRANSLATION_PHASE3_STATECHECK');
							$stateRow['state_valid'] = 0;
							$stateRow['state_unvalid'] = 0;
							$stateRow['state_missing'] = 0;
							$statecheck_i ++;
							break;
						}

						// we need to find an end, thats why the filter is at 10.000!
						$database->setQuery( $contentElement->createContentSQL( $stateRow['language_id'], null, 0, 10000,$filters ) );
						if( $rows = $database->loadObjectList() ) {
							$stateRow['state_valid'] = 0;
							$stateRow['state_unvalid'] = 0;
							$stateRow['state_missing'] = 0;

							for( $i=0; $i<count($rows); $i++ ) {
								$contentObject = new ContentObject( $stateRow['language_id'], $contentElement );
								$contentObject->readFromRow( $rows[$i] );
								$rows[$i] = $contentObject;

								switch( $contentObject->state ) {
									case 1:
										$stateRow['state_valid'] ++;
										break;
									case 0:
										$stateRow['state_unvalid'] ++;
										break;
									case -1:
									default:
										$stateRow['state_missing'] ++;
										break;
								}
							}
						}

					}

					if ($statecheck_i<count($translationStatus)-1) {
						$statecheck_i ++;
						$message = JText::sprintf('TRANSLATION_PHASE2_PUBLISHEDCHECK', ' ('. $translationStatus[$statecheck_i]['content'] .'/' .$translationStatus[$statecheck_i]['language'].')');
					} else {
						$message = JText::_('TRANSLATION_PHASE3_STATECHECK');
						$phase = 4;	// exit
					}

				} else {
					$message = JText::_('TRANSLATION_PHASE3_STATECHECK');
					$phase = 4; // exit
				}

				break;
		}


		return $translationStatus;
	}

	/**
	 * This method creates an overview of unpublished translations independed of the content element
	 * @return array 	of unpublished translations or null
	 */
	function _testUnpublisedTranslations() {
		global $database;
		$unpublishedTranslations = null;

		$sql = "select jfc.reference_table, jfc.reference_id, jfc.language_id, jfl.name as language" .
		"\n from #__jf_content as jfc, #__languages as jfl" .
		"\n where published=0  and jfc.language_id = jfl.id" .
		"\n group by jfc.reference_table, jfc.reference_id, jfc.language_id" .
		"\n limit 0, 50";
		$database->setQuery($sql);
		if( $rows = $database->loadObjectList() ) {
			foreach ($rows as $row) {
				$unpublished = array();
				$unpublished['reference_table'] = $row->reference_table;
				$unpublished['catid'] = $row->reference_table;
				$unpublished['reference_id'] = $row->reference_id;
				$unpublished['language_id'] = $row->language_id;
				$unpublished['language'] = $row->language;
				$unpublishedTranslations[] = $unpublished;
			}
		}
		return $unpublishedTranslations;
	}

	/**
	 * This method copies originals content items to one selected language
	 *
	 * @param unknown_type $original2languageInfo
	 * @param unknown_type $phase
	 * @param unknown_type $statecheck_i
	 * @param unknown_type $message
	 * @return array	Information result array
	 */
	function _copyOriginalToLanguage($original2languageInfo, &$phase, &$state_catid, $language_id, $overwrite, &$message) {
		global $database, $mosConfig_dbprefix;
		$sql = '';

		switch ($phase) {
			case 1:
				$original2languageInfo = array();

				$sql = "select distinct CONCAT('".$mosConfig_dbprefix."',reference_table) from #__jf_content";
				$database->setQuery( $sql );
				$tablesWithTranslations = $database->loadResultArray();

				$sql = "SHOW TABLES";
				$database->setQuery( $sql );
				$tables = $database->loadResultArray();

				$allContentElements = $this->_joomfishManager->getContentElements();

				foreach ($allContentElements as $catid=>$ce){
					$ceInfo = array();
					$ceInfo['name'] = $ce->Name;
					$ceInfo['catid'] = $catid;
					$ceInfo['total'] = '??';
					$ceInfo['existing'] = '??';
					$ceInfo['processed'] = '0';
					$ceInfo['copied'] = '0';
					$ceInfo['copy'] = false;

					$contentTable = $ce->getTable();
					$tablename = $mosConfig_dbprefix.$contentTable->Name;
					if (in_array($tablename,$tables)){
						// get total count of table entries
						$sql = 'SELECT COUNT(*) FROM ' .$tablename. ' AS c';
						if( $contentTable->Filter != ''){
							$sql .= ' WHERE ' .$contentTable->Filter;
						}

						$database->setQuery( $sql );
						$ceInfo['total'] = $database->loadResult();
					}
					$original2languageInfo[$catid] = $ceInfo;
				}
				$phase = 1;		// stays with 1 as the second phase needs the bottom to be clicked
				$message = JText::_('COPY2LANGUAGE_INFO');
				break;

			case 2:
				if( $state_catid != '' ) {
					// removing all content information which are not to be copied!
					$celements = explode(',', $state_catid);
					if( count($celements) < count($original2languageInfo)) {
						$shortList = array();
						foreach ($celements as $element) {
							$shortList[$element] = $original2languageInfo[$element];
						}
						$original2languageInfo = $shortList;
					}
				}
				$phase = 3;

			case 3:
				if( $state_catid != '' ) {
					$celements = explode(',', $state_catid);
					// copy the information per content element file, starting with the first in the list
					$catid = array_shift($celements);
					$catidCompleted = false;

					// coyping the information from the selected content element
					if($catid!='' && $language_id!=0) {
						// get's the config settings on how to store original files
						$storeOriginalText = ($this->_joomfishManager->getCfg('storageOfOriginal') == 'md5') ? false : true;

						// make sure we are only transfering data within parts (max 100 items at a time)
						$ceInfo =& $original2languageInfo[$catid];
						if(intval($ceInfo['processed']) < intval($ceInfo['total'])) {
							$contentElement = $this->_joomfishManager->getContentElement( $catid );
							$database->setQuery( $contentElement->createContentSQL( $language_id, null, $ceInfo['processed'], 10,array() ) );

							$rows = $database->loadObjectList();
							if ($database->getErrorNum()) {
								echo $database->stderr();
								return false;
							} else {
								for( $i=0; $i<count($rows); $i++ ) {
									$contentObject = new ContentObject( $language_id, $contentElement );
									$contentObject->readFromRow($rows[$i]);
									if( $overwrite || $contentObject->translation_id == 0) {
										$contentObject->copyContentToTranslation( $rows[$i], $rows[$i] );
										$contentObject->store();
										$ceInfo['copied'] += 1;
									}
									$rows[$i] = $contentObject;
								}
								$ceInfo['processed'] += $i;
								if($ceInfo['processed'] >= $ceInfo['total']) {
									$catidCompleted = true;
								}
							}
						}
					}
					if( $catidCompleted ) {
						if(count($celements)>0) {
							$state_catid = implode(',', $celements);
						} else {
							$state_catid = '';
						}
					}
				}

				$message = JText::_('COPY2LANGUAGE_PROCESS');
				if( $state_catid == '') {
					$phase = 4;		// Successfully finished phase 3
					$message = JText::_('COPY2LANGUAGE_COMPLETED');
				}
				break;
		}

		return $original2languageInfo;
	}

	/**
	 * Upgrades the database tables from one version to another
	 *
	 * @param int $backupTables
	 * @param int $renameTables
	 * @return array	sumamry Information
	 *
	 */
	function _upgradeInstallation( $backupTables, $renameTables ) {
		global $database;

		$summary = array();
		$summary['state'] = false;
		// Default values
		$summary['mbf_module_unpublished'] = false;
		$summary['mbf_module_unpublished_error'] = '';
		$summary['mbf_bot_unpublished'] = false;
		$summary['mbf_bot_unpublished_error'] = '';
		$summary['jf_content_backup'] = false;
		$summary['jf_content_backup_error'] = '';
		$summary['jf_languages_backup'] = false;
		$summary['jf_languages_backup_error'] = '';
		$summary['jf_content_deleted'] = false;
		$summary['jf_content_deleted_error'] = '';
		$summary['jf_content_copied'] = false;
		$summary['jf_content_copied_error'] = '';
		$summary['jf_languages_deleted'] = false;
		$summary['jf_languages_deleted_error'] = '';
		$summary['jf_languages_copied'] = false;
		$summary['jf_languages_copied_error'] = '';

		// unpublish mambelfish mambots and modules
		$database->setQuery( "UPDATE #__modules SET published = 0 WHERE LOWER(module) = 'mod_mambelfish'");
		if( !$summary['mbf_module_unpublished'] = $database->query() ) {
			$summary['mbf_module_unpublished_error'] = $database->getErrorMsg();
			return $summary;
		}
		$database->setQuery( "UPDATE #__mambots SET published = 0 WHERE LOWER(element) = 'mbfcontent.searchbot'");
		if( !$summary['mbf_bot_unpublished'] = $database->query() ) {
			$summary['mbf_bot_unpublished_error'] = $database->getErrorMsg();
			return $summary;
		}


		if( $backupTables ) {
			// renaming existing JoomFish tables
			$database->setQuery( 'DROP TABLE IF EXISTS #__jf_content_bak;');
			$database->query();

			$sql = "CREATE TABLE `#__jf_content_bak` ("
			. "\n `id` int( 10 ) unsigned NOT NULL AUTO_INCREMENT ,"
			. "\n `language_id` int( 11 ) NOT NULL default '0',"
			. "\n `reference_id` int( 11 ) NOT NULL default '0',"
			. "\n `reference_table` varchar( 100 ) NOT NULL default '',"
			. "\n `reference_field` varchar( 100 ) NOT NULL default '',"
			. "\n `value` mediumtext NOT NULL ,"
			. "\n `original_value` varchar( 255 ) default NULL ,"
			. "\n `original_text` text default NULL ,"
			. "\n `modified` datetime NOT NULL default '0000-00-00 00:00:00',"
			. "\n `modified_by` int( 11 ) unsigned NOT NULL default '0',"
			. "\n `published` tinyint( 1 ) unsigned NOT NULL default '0',"
			. "\n PRIMARY KEY ( `id` )"
			. "\n )";
			$database->setQuery( $sql );
			if( !$summary['jf_content_backup'] = $database->query() ) {
				$summary[ 'jf_content_backup_error' ] = $database->getErrorMsg();
				return $summary;
			}

			$sql = "INSERT INTO `#__jf_content_bak` SELECT * FROM `#__jf_content`";
			$database->setQuery( $sql );
			if( !$summary['jf_content_backup'] = $database->query() ) {
				$summary[ 'jf_content_backup_error' ] = $database->getErrorMsg();
				return $summary;
			}

			// language table update
			$database->setQuery( 'DROP TABLE IF EXISTS #__languages_bak;');
			$database->query();

			$sql = "CREATE TABLE `#__languages_bak` ("
			. "\n `id` int(11) NOT NULL auto_increment,"
			. "\n `name` varchar(100) NOT NULL default '',"
			. "\n `active` tinyint(1) NOT NULL default '0',"
			. "\n `iso` varchar(10) default NULL,"
			. "\n `code` varchar(20) NOT NULL default '',"
			. "\n `shortcode` varchar(20) NOT NULL default '',"
			. "\n `image` varchar(100) default NULL,"
			. "\n `fallback_code` varchar(20) NOT NULL default '',"
			. "\n `params` text NOT NULL default '',"
			. "\n `ordering` int(11) NOT NULL default '0',"
			. "\n PRIMARY KEY ( `id` )"
			. "\n )";
			$database->setQuery( $sql );
			if( !$summary['jf_languages_backup'] = $database->query() ) {
				$summary[ 'jf_languages_backup_error' ] = $database->getErrorMsg();
				return $summary;
			}

			$sql = "INSERT INTO `#__languages_bak` SELECT * FROM `#__languages`";
			$database->setQuery( $sql );
			if( !$summary['jf_languages_backup'] = $database->query() ) {
				$summary[ 'jf_languages_backup_error' ] = $database->getErrorMsg();
				return $summary;
			}
		}

		$database->setQuery( "SHOW TABLES LIKE '%mbf_%'" );
		$database->query();
		$rows = $database->loadResultArray();
		$oldContentTable = '';
		$oldLanguageTable = '';
		foreach ($rows as $row) {
			if( ereg( 'mbf_content', $row ) ) {
				$oldContentTable = $row;
			} elseif ( ereg( 'mbf_language', $row ) ) {
				$oldLanguageTable = $row;
			}
		}

		if( $oldContentTable != '' ) {
			// Delete existing records
			$database->setQuery( 'DELETE FROM #__jf_content');
			if( !$summary['jf_content_deleted'] = $database->query() ) {
				$summary[ 'jf_content_deleted_error' ] = $database->getErrorMsg();
				return $summary;
			}

			// copy data over (doing md5 at the same time!)
			$database->setQuery( "INSERT INTO #__jf_content "
			. "\n(id, language_id, reference_id, reference_table, reference_field, value, original_value, modified, modified_by, published)"
			. "\n SELECT id, language_id, reference_id,  reference_table, reference_field, value, md5(original_value), modified, modified_by, published"
			. "\nFROM " .$oldContentTable );
			if( !$summary['jf_content_copied'] = $database->query() ) {
				$summary[ 'jf_content_copied_error' ] = $database->getErrorMsg();
				return $summary;
			}

			$summary['state'] = true;
		}

		if( $oldLanguageTable != '' ) {
			// Delete existing records
			$database->setQuery( 'DELETE FROM #__languages');
			if( !$summary['jf_languages_deleted'] = $database->query() ) {
				$summary[ 'jf_languages_deleted_error' ] = $database->getErrorMsg();
				return $summary;
			}

			// copy data over (doing md5 at the same time!)
			$database->setQuery( "INSERT INTO #__languages "
			. "\n(`id`, `name`, `active`, `iso`, `code`, `image`, `ordering`)"
			. "\n SELECT `id`, `name`, `active`, `iso`, `mambo`, `image`, `ordering`"
			. "\nFROM " .$oldLanguageTable );
			if( !$summary['jf_languages_copied'] = $database->query() ) {
				$summary[ 'jf_languages_copied_error' ] = $database->getErrorMsg();
				return $summary;
			}

			$summary['state'] = true;
		}
		return $summary;
	}

	/**
	* Utility function find all directories within a parent directory
	* @param string The parent directory path
	* @param boolean True if to prepend the full path to the file name
	*/
	function _findDirectories( $path, $fullpath=false  ) {
		$arr = array();
		if (!@is_dir( $path )) {
			return $arr;
		}
		$handle = opendir( $path );

		while ($file = readdir($handle)) {
			$dir = mosPathName( $path.'/'.$file, false );
			if (is_dir( $dir ) && substr($file, 0, 1) != '.' ) {
				if( $fullpath ) {
					$arr[] = trim( $dir );
				} else {
					$arr[] = trim( $file );
				}
			}
		}
		closedir($handle);
		asort($arr);
		return $arr;
	}
}

/**
 * This class allows general installation of files related to the Joom!Fish project
 * It is a light version of the mosInstaller class without the particular handling of
 * special package XML files within the archieves. All XML files are automatically
 * interpreterted as content element files and installed in the related directories
 *
 */
class jfInstaller {
	var $_iswin			= false;
	var $errno			= 0;
	var $error			= "";
	var $_unpackdir		= "";

	/** @var string The directory where the element is to be installed */
	var $_elementdir 		= '';
	var $_uploadfile		= null;
	var $_realname			= null;
	var $_contentelements	= array();

	/**
	* Constructor
	*/
	function jfInstaller() {
		global $mosConfig_absolute_path;
		$this->_iswin = (substr(PHP_OS, 0, 3) == 'WIN');
		$this->_elementdir = mosPathName( $mosConfig_absolute_path . '/administrator/components/com_joomfish/contentelements' );

	}

	/**
	 * Installation of a single file or archive for the joomfish files
	 * @param array uploadfile	retrieved information transferred by the upload form
	 */
	function install( $uploadfile = null ) {
		if( $uploadfile === null ) {
			return false;
		}
		$this->_uploadfile = $uploadfile['tmp_name'];
		$this->_realname = $uploadfile['name'];

		return $this->upload();
	}

	/**
	* Uploads and unpacks a file
	* @return boolean True on success, False on error
	*/
	function upload() {
		if( !eregi( '.xml$', $this->_realname ) ) {
			if(! $this->extractArchive() ) {
				return false;
			}
		}

		if( !is_array( $this->_uploadfile ) ) {
			if(! @copy($this->_uploadfile, $this->_elementdir . $this->_realname) ) {
				$this->errno = 2;
				$this->error = JText::_('FILEUPLOAD_ERROR');
				return false;
			}
		} else {
			foreach ($this->_uploadfile as $file ) {
				if(! @copy($this->_unpackdir . $file, $this->_elementdir . $file) ) {
					$this->errno = 2;
					$this->error = JText::_('FILEUPLOAD_ERROR');
					return false;
				}
			}
		}
		return true;
	}

	/**
	* Extracts the package archive file
	* @return boolean True on success, False on error
	*/
	function extractArchive() {
		global $mosConfig_absolute_path;

		$base_Dir 		= mosPathName( $mosConfig_absolute_path . '/media' );

		$archivename 	= $base_Dir . $this->_realname;
		$tmpdir 		= uniqid( 'install_' );

		$extractdir 	= mosPathName( $base_Dir . $tmpdir );
		$archivename 	= mosPathName( $archivename, false );
		$this->_unpackdir = $extractdir;

		if (eregi( '.zip$', $archivename )) {
			// Extract functions
			require_once( $mosConfig_absolute_path . '/administrator/includes/pcl/pclzip.lib.php' );
			require_once( $mosConfig_absolute_path . '/administrator/includes/pcl/pclerror.lib.php' );
			$zipfile = new PclZip( $this->_uploadfile );
			if($this->_iswin) {
				define('OS_WINDOWS',1);
			} else {
				define('OS_WINDOWS',0);
			}

			$ret = $zipfile->extract( PCLZIP_OPT_PATH, $extractdir );
			if($ret == 0) {
				$this->errno = 1;
				$this->error = 'Unrecoverable error "'.$zipfile->errorName(true).'"';
				return false;
			}
		} else {
			require_once( $mosConfig_absolute_path . '/includes/Archive/Tar.php' );
			$archive = new Archive_Tar( $this->_uploadfile );
			$archive->setErrorHandling( PEAR_ERROR_PRINT );

			if (!$archive->extractModify( $extractdir, '' )) {
				$this->setError( 1, 'Extract Error' );
				return false;
			}
		}

		// Try to find the correct install dir. in case that the package have subdirs
		// Save the install dir for later cleanup
		$this->_uploadfile = mosReadDirectory( $extractdir, '' );

		if (count( $this->_uploadfile ) == 1) {
			if (is_dir( $extractdir . $this->_uploadfile[0] )) {
				$this->_unpackdir = mosPathName( $extractdir . $this->_uploadfile[0] );
				$this->_uploadfile = mosReadDirectory( $extractdir, '' );
			}
		}

		return true;
	}
}
?>
